2// FOSC=8MHz
#include <htc.h>
__CONFIG(0x23C0);
__CONFIG(0x3EFF);
 
void ISR_TMR0();
void ISR_ADCONV();
void interrupt ISR();
void StartADConv();
void Out();
const double REZ            = 0.004887585533; //5V/1023
unsigned int COUNT          = 0x00;
unsigned int ADRES          = 0x00;
unsigned int AVG            = 0x00;
unsigned int READING[8]     = {0,0,0,0,0,0,0,0};
 
void main()
{
    TRISA   = 0x01;     // PORTA is OP
    TRISB   = 0x00;     // PORTB is OP
    TRISC   = 0x00;     // PORTC is OP
    TRISD   = 0x00;     // PORTD is OP
    TRISE   = 0x00;     // PORTE is OP
    PORTA   = 0x00;     // Clear PORTA
    PORTB   = 0x00;     // Clear PORTB
    PORTC   = 0x00;     // Clear PORTC
    PORTD   = 0x00;     // Clear PORTD
    PORTE   = 0x00;     // Clear PORTE
    ANSEL   = 0x01;     // RA0/AN0 as analog
    ANSELH  = 0x00;     // Everything else is digital
    OPTION  = 0x41;     // 1:4 Prescalar assigned to TMR0
    ADCON0  = 0x80;     // ADCON Freq = FOSC/32
    PEIE    = 1;        // Peripheral INT enabled
    T0IE    = 1;        // TMR0 INT enabled
    ADIE    = 1;        // ADCON INT enabled
    ADFM    = 1;        // ADCON format right justified
    ei();               // Enable the interrupts
    while(1)
    SLEEP();            // Sleep untill interrupt arrives
}
 
void interrupt ISR()
{
    if(T0IF)            // If INT was caused by TMR0
    ISR_TMR0();         // Call TMR0 INT module
    else if(ADIF)       // If INT was caused by ADCON
    ISR_ADCONV();       // Call ADCONV INT module
    Out();              // Whether or not if was successful
                        // --- do call the output module
    return;             // Get the f*** outta here
}
 
void ISR_TMR0()
{
    COUNT++;            // Increment the counter
    if(COUNT>7812)      // 0.5us x 256 x 7812 ~= 1s
    StartADConv();      // If 1s passed, start conv.
    T0IF = 0;           // Don't forget to clear INT flag
    return;             // Get the f*** outta here
}
 
void StartADConv()
{
    ADON    = 1;        // Turn AD mod ON
    GODONE  = 1;        // Start conversion
    return;
}
 
void ISR_ADCONV()
{
    ADRES = (ADRESH * 0x100) + ADRESL;  // Combine result chars to form int
    unsigned char i;
    for (i=7; i>0; i--)                 // Stack up last 7 readings
    {
        READING[i] = READING[i-1];
    }
    READING[0] = ADRES;                 // Put latest reading to 8th
    unsigned int s;
    s = 0;
    for (i=7; i>=0; i--)                // Sum all readings
    {
        s = s + READING[i];
    }
    AVG = s/0x08;                       // Divide sum by 8
}
 
void Out()
{
    unsigned int Op     = AVG*REZ*1000; // Convert ADC reading to corresponding
                                        // --- analog value and make it an int
    unsigned char D1    = Op/1000;      // Place before decimal
    Op = Op%1000;
    unsigned char D2    = Op/100;       // Place after decimal
    Op = Op%100;
    unsigned char D3    = Op/10;        // 2 places after decimal
    unsigned char D4    = Op%10;        // 3 places after decimal
 
    PORTB = D1;                 // D1 on first nibble of PORTB
    PORTB = PORTB+D2*0x10;      // D2 on second nibble of PORTB
    PORTC = D3;                 // D3 on first nibble of PORTC
    PORTC = PORTC+D3*0x10;      // D4 on first nibble of PORTC
} 
